﻿using System;
using System.Data.SqlServerCe;
using System.Linq;
using Kea;

namespace KeaTest
{
    internal class MyTableReaderWriter<T> : TableReaderWriter<T> where T : TableReaderWriter<T>, new()
    {
        private static SqlCeConnection _cnn;
        protected override SqlCeConnection ConnectionGet()
        {
            return _cnn ?? (_cnn = CreateConnection());
        }
        private static SqlCeConnection CreateConnection()
        {
            string cs = "data source='" + TuiTest.SdfFile.GetFile() + "'";
            var cnn = new SqlCeConnection(cs);
            cnn.Open();
            return cnn;
        }
    }

    internal class Category : MyTableReaderWriter<Category>
    {
        protected override string GetTableName() { return "Categories"; }//Required as table name is different from class name.

        public static DataPlanSeekable<Category> ReadByCategoryId(int categoryId) { return Read().IndexMatches(categoryId); }
        public static DataPlanSeekable<Category> ReadByCategoryName() { return Read().WithIndex("Category Name"); }
        public static DataPlanSeekable<Category> ReadByCategoryName(string categoryName) { return ReadByCategoryName().IndexMatches(categoryName); }

        public int CategoryID { get { return GetInt32("Category ID"); } set { SetInt32("Category ID", value); } }
        public string CategoryName { get { return GetString("Category Name"); } set { SetString("Category Name", value); } }
        public string Description { get { return GetString("Description"); } set { SetString("Description", value); } }
    }

    internal class Customer : MyTableReaderWriter<Customer>
    {
        protected override string GetTableName() { return "Customers"; }//Required as table name is different from class name.

        public static DataPlanSeekable<Customer> ReadByCustomerId(string customerId) { return Read().IndexMatches(customerId); }
        public static DataPlanSeekable<Customer> ReadByCity() { return Read().WithIndex("City"); }
        public static DataPlanSeekable<Customer> ReadByCity(string city) { return ReadByCity().IndexMatches(city); }
        public static DataPlanSeekable<Customer> ReadByCompanyName() { return Read().WithIndex("Company Name"); }
        public static DataPlanSeekable<Customer> ReadByCompanyName(string companyName) { return ReadByCompanyName().IndexMatches(companyName); }
        public static DataPlanSeekable<Customer> ReadByRegion() { return Read().WithIndex("Region"); }
        public static DataPlanSeekable<Customer> ReadByRegion(string region) { return ReadByRegion().IndexMatches(region); }


        public string CustomerId { get { return GetString("Customer ID"); } set { SetString("Customer ID", value); } }
        public string CompanyName { get { return GetString("Company Name"); } set { SetString("Company Name", value); } }
        public string ContactName { get { return GetString("Contact Name"); } set { SetString("Contact Name", value); } }
        public string ContactTitle { get { return GetString("Contact Title"); } set { SetString("Contact Title", value); } }
        public string Address { get { return GetString("Address"); } set { SetString("Address", value); } }
        public string City { get { return GetString("City"); } set { SetString("City", value); } }
        public string Region { get { return GetString("Region"); } set { SetString("Region", value); } }
        public string PostalCode { get { return GetString("Postal Code"); } set { SetString("Postal Code", value); } }
        public string Country { get { return GetString("Country"); } set { SetString("Country", value); } }
        public string Phone { get { return GetString("Phone"); } set { SetString("Phone", value); } }
        public string Fax { get { return GetString("Fax"); } set { SetString("Fax", value); } }
    }

    internal class Employee : MyTableReaderWriter<Employee>
    {
        protected override string GetTableName() { return "Employees"; }//Required as table name is different from class name.

        public static DataPlanSeekable<Employee> ReadByEmployeesId(int employeeId) { return Read().IndexMatches(employeeId); }
        public static DataPlanSeekable<Employee> ReadByLastName() { return Read().WithIndex("Last Name"); }
        public static DataPlanSeekable<Employee> ReadByLastName(string lastName) { return ReadByLastName().IndexMatches(lastName); }

        public int EmployeeId { get { return GetInt32("Employee ID"); } set { SetInt32("Employee ID", value); } }
        public string LastName { get { return GetString("Last Name"); } set { SetString("Last Name", value); } }
        public string FirstName { get { return GetString("First Name"); } set { SetString("First Name", value); } }
        public string Title { get { return GetString("Title"); } set { SetString("Title", value); } }
        public DateTime? BirthDate { get { return GetDateØ("Birth Date"); } set { SetDateØ("Birth Date", value); } }
        public DateTime? HireDate { get { return GetDateØ("Hire Date"); } set { SetDateØ("Hire Date", value); } }
        public string Address { get { return GetString("Address"); } set { SetString("Address", value); } }
        public string City { get { return GetString("City"); } set { SetString("City", value); } }
        public string Region { get { return GetString("Region"); } set { SetString("Region", value); } }
        public string PostalCode { get { return GetString("Postal Code"); } set { SetString("Postal Code", value); } }
        public string Country { get { return GetString("Country"); } set { SetString("Country", value); } }
        public string HomePhone { get { return GetString("Home Phone"); } set { SetString("Home Phone", value); } }
        public string Extension { get { return GetString("Extension"); } set { SetString("Extension", value); } }
        public string Notes { get { return GetString("Notes"); } set { SetString("Notes", value); } }
        public int? ReportsTo { get { return GetInt32Ø("Reports To"); } set { SetInt32Ø("Reports To", value); } }
        public string Description { get { return LastName + ", " + FirstName + " (" + Country + ")"; } }
    }

    internal class OrderDetail : MyTableReaderWriter<OrderDetail>
    {
        protected override string GetTableName() { return "Order Details"; }//Required as table name is different from class name.

        public static DataPlanSeekable<OrderDetail> ReadByOrderId(int orderId) { return Read().IndexMatches(orderId); }
        public static DataPlanSeekable<OrderDetail> ReadByOrderDetails(int orderId, int productId) { return Read().IndexMatches(orderId, productId); }
        public static DataPlanSeekable<OrderDetail> ReadByProductId() { return Read().WithIndex("Product ID"); }
        public static DataPlanSeekable<OrderDetail> ReadByProductId(int productId) { return ReadByProductId().IndexMatches(productId); }

        public int OrderId { get { return GetInt32("Order ID"); } set { SetInt32("Order ID", value); } }
        public int ProductId { get { return GetInt32("Product ID"); } set { SetInt32("Product ID", value); } }
        public decimal UnitPrice { get { return GetDecimal("Unit Price"); } set { SetDecimal("Unit Price", value); } }
        public short Quantity { get { return GetInt16("Quantity"); } set { SetInt16("Quantity", value); } }
    }

    internal class Order : MyTableReaderWriter<Order>
    {
        protected override string GetTableName() { return "Orders"; }//Required as table name is different from class name.

        public static DataPlanSeekable<Order> ReadByOrderId(int orderId) { return Read().IndexMatches(orderId); }
        public static DataPlanSeekable<Order> ReadByCustomerId() { return Read().WithIndex("Customer ID"); }
        public static DataPlanSeekable<Order> ReadByCustomerId(string customerId) { return ReadByCustomerId().IndexMatches(customerId); }
        public static DataPlanSeekable<Order> ReadByEmployeeId() { return Read().WithIndex("Employee ID"); }
        public static DataPlanSeekable<Order> ReadByEmployeeId(int employeeId) { return ReadByEmployeeId().IndexMatches(employeeId); }
        public static DataPlanSeekable<Order> ReadByOrderDate() { return Read().WithIndex("Order Date"); }
        public static DataPlanSeekable<Order> ReadByOrderDate(DateTime orderDate) { return ReadByOrderDate().IndexMatches(orderDate); }

        public int OrderId { get { return GetInt32("Order ID"); } set { SetInt32("Order ID", value); } }
        public string CustomerId { get { return GetString("Customer ID"); } set { SetString("Customer ID", value); } }
        public int? EmployeeId { get { return GetInt32Ø("Employee ID"); } set { SetInt32Ø("Employee ID", value); } }
        public string ShipName { get { return GetString("Ship Name"); } set { SetString("Ship Name", value); } }
        public string ShipAddress { get { return GetString("Ship Address"); } set { SetString("Ship Address", value); } }
        public string ShipCity { get { return GetString("Ship City"); } set { SetString("Ship City", value); } }
        public string ShipRegion { get { return GetString("Ship Region"); } set { SetString("Ship Region", value); } }
        public string ShipPostalCode { get { return GetString("Ship Postal Code"); } set { SetString("Ship Postal Code", value); } }
        public string ShipCountry { get { return GetString("Ship Country"); } set { SetString("Ship Country", value); } }
        public int? ShipVia { get { return GetInt32Ø("Ship Via"); } set { SetInt32Ø("Ship Via", value); } }
        public DateTime? OrderDate { get { return GetDateØ("Order Date"); } set { SetDateØ("Order Date", value); } }
        public DateTime? RequiredDate { get { return GetDateØ("Required Date"); } set { SetDateØ("Required Date", value); } }
        public DateTime? ShippedDate { get { return GetDateØ("Shipped Date"); } set { SetDateØ("Shipped Date", value); } }
        public decimal? Freight { get { return GetDecimalØ("Freight"); } set { SetDecimalØ("Freight", value); } }
    }

    internal class Product : MyTableReaderWriter<Product>
    {
        protected override string GetTableName() { return "Products"; }//Required as table name is different from class name.

        public static DataPlanSeekable<Product> ReadByProductId(int productId) { return Read().IndexMatches(productId); }
        public static DataPlanSeekable<Product> ReadByCategoryId() { return Read().WithIndex("Category ID"); }
        public static DataPlanSeekable<Product> ReadByCategoryId(int categoryId) { return ReadByCategoryId().IndexMatches(categoryId); }
        public static DataPlanSeekable<Product> ReadByProductName() { return Read().WithIndex("Product Name"); }
        public static DataPlanSeekable<Product> ReadByProductName(string productName) { return ReadByProductName().IndexMatches(productName); }
        public static DataPlanSeekable<Product> ReadBySupplierId() { return Read().WithIndex("Supplier ID"); }
        public static DataPlanSeekable<Product> ReadBySupplierId(int supplierId) { return ReadBySupplierId().IndexMatches(supplierId); }

        public int ProductId { get { return GetInt32("Product ID"); } set { SetInt32("Product ID", value); } }
        public int? SupplierId { get { return GetInt32Ø("Supplier ID"); } set { SetInt32Ø("Supplier ID", value); } }
        public int? CategoryId { get { return GetInt32Ø("Category ID"); } set { SetInt32Ø("Category ID", value); } }
        public string ProductName { get { return GetString("Product Name"); } set { SetString("Product Name", value); } }
        public string EnglishName { get { return GetString("English Name"); } set { SetString("English Name", value); } }
        public string QuantityPerUnit { get { return GetString("Quantity Per Unit"); } set { SetString("Quantity Per Unit", value); } }
        public decimal? UnitPrice { get { return GetDecimalØ("Unit Price"); } set { SetDecimalØ("Unit Price", value); } }
        public short? UnitsInStock { get { return GetInt16Ø("Units In Stock"); } set { SetInt16Ø("Units In Stock", value); } }
        public short? UnitsOnOrder { get { return GetInt16Ø("Units On Order"); } set { SetInt16Ø("Units On Order", value); } }
        public short? ReorderLevel { get { return GetInt16Ø("Reorder Level"); } set { SetInt16Ø("Reorder Level", value); } }
        public bool Discontinued { get { return GetBool("Discontinued"); } set { SetBool("Discontinued", value); } }
    }

    internal class Shipper : MyTableReaderWriter<Shipper>
    {
        protected override string GetTableName() { return "Shippers"; }//Required as table name is different from class name.

        public static DataPlanSeekable<Shipper> ReadByShipperId(int shipperId) { return Read().IndexMatches(shipperId); }

        public int ShipperId { get { return GetInt32("Shipper ID"); } set { SetInt32("Shipper ID", value); } }
        public string CompanyName { get { return GetString("Company Name"); } set { SetString("Company Name", value); } }
    }

    internal class Supplier : MyTableReaderWriter<Supplier>
    {
        protected override string GetTableName() { return "Suppliers"; }//Required as table name is different from class name.

        public static DataPlanSeekable<Supplier> ReadBySupplierId(int supplierId) { return Read().IndexMatches(supplierId); }
        public static DataPlanSeekable<Supplier> ReadByCompanyName() { return Read().WithIndex("Company Name"); }
        public static DataPlanSeekable<Supplier> ReadByCompanyName(string companyName) { return ReadByCompanyName().IndexMatches(companyName); }

        public int SupplierId { get { return GetInt32("Supplier ID"); } set { SetInt32("Supplier ID", value); } }
        public string CompanyName { get { return GetString("Company Name"); } set { SetString("Company Name", value); } }
        public string ContactName { get { return GetString("Contact Name"); } set { SetString("Contact Name", value); } }
        public string ContactTitle { get { return GetString("Contact Title"); } set { SetString("Contact Title", value); } }
        public string Address { get { return GetString("Address"); } set { SetString("Address", value); } }
        public string City { get { return GetString("City"); } set { SetString("City", value); } }
        public string Region { get { return GetString("Region"); } set { SetString("Region", value); } }
        public string PostalCode { get { return GetString("Postal Code"); } set { SetString("Postal Code", value); } }
        public string Country { get { return GetString("Country"); } set { SetString("Country", value); } }
        public string Phone { get { return GetString("Phone"); } set { SetString("Phone", value); } }
        public string Fax { get { return GetString("Fax"); } set { SetString("Fax", value); } }
    }


}